#include "FileIO.h"
#include "State.h"
#include "SystemData.h"

#include <iostream>
#include <cstdlib>
#include <iomanip>

using namespace std;

namespace RSIM{
namespace FileIO{

///////////////////////////////////////////////////////

void writeArrayToFile(double const* const*ptr, const int num_elements, const int num_array, const char FileName[], const int precision){
        fstream OpFile; 
        if(checkFileExists(FileName)){
                cout<<"writeArrayToFile(): given file already exists. (o)verwrite, (a)bort ?\n";
                char ch;
                do{
                        cin>>ch;
                }while((ch!='o') && (ch!='a'));
                if(ch=='a')
                        exit(0);
        }
        OpFile.open(FileName,ios::out);
        
        for(int i=0;i<num_elements;++i){
                for(int j=0;j<num_array;++j){
                        OpFile<<setprecision(precision)<<ptr[j][i]<<"\t";			
                }
                OpFile<<endl;
        }
        
        OpFile.close();
        
}

///////////////////////////////////////////////////////

void write_append_ArrayToFile(double const* const*ptr, const int num_elements, const int num_array, const char FileName[],  const int precision){
        fstream OpFile; 	
        OpFile.open(FileName,ios::app | ios::out );
        for(int i=0;i<num_elements;++i){
                for(int j=0;j<num_array;++j){
                        OpFile<<setprecision(precision)<<ptr[j][i]<<"\t";			
                }
                OpFile<<endl;
        }
        OpFile.close();
}

///////////////////////////////////////////////////////

void write_append_SingleArrayToFile(const double& val, double const*ptr, const int num_elements, const char FileName[],  const int precision){
        fstream OpFile; 	
        OpFile.open(FileName,ios::app | ios::out );
        OpFile<<val<<" ";
        for(int i=0;i<num_elements;++i)
                OpFile<<setprecision(precision)<<ptr[i]<<" ";		
        OpFile<<endl;
        OpFile.close();
}

///////////////////////////////////////////////////////

void write_append_SingleArrayToFile(fstream& OpFile, const double& val, double const*ptr, const int num_elements, const char FileName[],  const int precision){
        OpFile<<val<<" ";
        for(int i=0;i<num_elements;++i)
                OpFile<<setprecision(precision)<<ptr[i]<<" ";		
        OpFile<<endl;
}

void appendStateVectorToFile(const State& state,  
                        fstream& OpFile, 
                        const int precision){
        
        OpFile<<state.getTime()<<" ";
        
        const int& nq = state.getNQ();
        const int& nu = state.getNU();
        
        const double *q = state.getQ();
        const double *u = state.getU();
                
        OpFile<<setprecision(precision);
        
        for(int i=0;i<nq;++i)
                OpFile<<q[i]<<" ";
        for(int i=0;i<nu;++i)
                OpFile<<u[i]<<" ";
        OpFile<<endl;
}

///////////////////////////////////////////////////////

bool checkFileExists(const char FileName[]){
        fstream fin;
        fin.open(FileName,ios::in);
        if(fin.is_open()){
                fin.close();
                return true;
        }
        fin.close();
        return false;
}

///////////////////////////////////////////////////////

void appendStateVectorToFile(const SystemData& Data,  
                             fstream& OpFile, 
                             const int& precision){
        OpFile<<Data.Time()<<" ";
        
        const int& nY = Data.getNY();
        Vector Y(nY);
        Data.extractYFromState(Y);
        const double *y = Y.Ptr();
        
        OpFile<<setprecision(precision);
        
        for(int i=0;i<nY;++i)
                OpFile<<y[i]<<" ";        
        OpFile<<endl;
}
                             
///////////////////////////////////////////////////////

}// namespaec FileIO
}// namespace RSIM